#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "struct.h"
#include <time.h>

pthread_cond_t condition = PTHREAD_COND_INITIALIZER; /* Création de la condition */
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /* Création du mutex */

void* threadAlarme (void* arg);
void* threadD (void* arg);
char DetectionTouche_Detect (ST_SEG* pSeg);
int DetectionTouche_kbhit(int* valeur,struct termios* new_settings) ;
void* threadD (void* arg);
void* threadAlarme (void* arg);


int main (void)
{
	pthread_t monThreadD;
	pthread_t monThreadAlarme;

	pthread_create (&monThreadD, NULL, threadD, (void*)NULL);
	pthread_create (&monThreadAlarme, NULL, threadAlarme, (void*)NULL); /* Création des threads */

	pthread_join (monThreadD, NULL);
	pthread_join (monThreadAlarme, NULL); /* Attente de la fin des threads */

	return 0;
}

void* threadD (void* arg)
{
	int compteur = 0, nombre = 0;
	char Toto=0;
	
	

	while(1) /* Boucle infinie */
	{
		Toto = DetectionTouche_Detect(NULL);
		if(Toto == 0 && alarm(1)) /* Si compteur est plus grand ou égal à 20 */
		;
		
		else
		{
			pthread_mutex_lock (&mutex); /* On verrouille le mutex */
			pthread_cond_signal (&condition); /* On délivre le signal : condition remplie */
			pthread_mutex_unlock (&mutex); /* On déverrouille le mutex */
			pthread_exit(NULL); /* Fin du thread */
		}
	}
}

void* threadAlarme (void* arg)
{
	while(1) /* Boucle infinie */
	{
		pthread_mutex_lock(&mutex); /* On verrouille le mutex */
		pthread_cond_wait (&condition, &mutex); /* On attend que la condition soit remplie */
		printf("\nUne touche a ete appuyer."); 
		pthread_mutex_unlock(&mutex); /* On déverrouille le mutex */
		pthread_exit(NULL); /* Fin du thread */
	}
}



typedef struct data {
    int var;
    pthread_mutex_t mutex;
} data;


/*************************************************
**  Zone de declaration des Fonctions PUBLIC    **
*************************************************/

/*************************************************************************
**  [DetectionTouche_Detect]               		    					**
**  	Appel toutes les fonctions pour pouvoir detecter une touche     **
**																		**
**	Entrees : NULL								                        **
**																		**
**																		**
**	Sorties : char														**
**				carac - Renvoi le caractere tape                        **
**									                                    **
**************************************************************************/
char DetectionTouche_Detect (ST_SEG* pSeg)
{
	struct termios initial_settings;
	struct termios new_settings;
	
	int carac = 0; 

	DetectionTouche_Init_Keyboard(&initial_settings,&new_settings); 
	
	if (pSeg != NULL)
	{
		while(carac == 0 && pSeg->Un_entier == 12)
		{  
			DetectionTouche_kbhit(&carac,&new_settings);
		} 
	}
	else
	{
		while(carac == 0)
		{  
			// Fonc 1 : Dectection touche
			// Fonc 2 : Attend
			// 2 Thread -> Fonc 1 et 2
			// Fonc 1 -> Dectection en continue
			// Fonc 2 -> Compteur d'attente  
			DetectionTouche_kbhit(&carac,&new_settings);
		
		} 
		
	}

	DetectionTouche_Close_Keyboard(&initial_settings);
	return carac; 
	
}

/*************************************************
**  Zone de declaration des Fonctions PRIVE     **
*************************************************/

/*************************************************************************
**  [DetectionTouche_Init_Keyboard]                 		    		**
**  	Initialisatoin du clavier								        **
**																		**
**	Entrees : NULL								                        **
**																		**
**																		**
**	Sorties : NULL														**
**									                                    **
**									                                    **
**************************************************************************/
void DetectionTouche_Init_Keyboard(struct termios* initial_settings,struct termios* new_settings) 
{	
	tcgetattr(0,initial_settings); 
	memcpy(new_settings,initial_settings,sizeof(struct termios));
	new_settings->c_lflag &= ~ICANON; 
	new_settings->c_lflag &= ~ECHO; 
	new_settings->c_lflag &= ~ISIG; 
	new_settings->c_cc[VMIN] = 1; 
	new_settings->c_cc[VTIME] = 0; 
	tcsetattr(0, TCSANOW,new_settings); 	
}


/*************************************************
**  Zone de declaration des Fonctions PRIVE     **
*************************************************/

/*************************************************************************
**  [DetectionTouche_Close_Keyboard]                 		    		**
**  	Initialisatoin du clavier								        **
**																		**
**	Entrees : NULL								                        **
**																		**
**																		**
**	Sorties : NULL														**
**									                                    **
**									                                    **
**************************************************************************/
void DetectionTouche_Close_Keyboard(struct termios* initial_settings) 
{ 
	tcsetattr(0, TCSANOW, initial_settings); 
}


/*************************************************************************
**  [DetectionTouche_kbhit]        			         		    		**
**  	Permet de rendre non bloquant le getch					        **
**																		**
**	Entrees : NULL								                        **
**																		**
**																		**
**	Sorties : int														**
**				Si la valeur retournee est 1 alors il y a detection 	**
**				d'un caractere											**
**				Si la valeur retournee est 0 alors rien detecte         **
**									                                    **
**************************************************************************/
int DetectionTouche_kbhit(int* valeur,struct termios* new_settings) 
{ 
	int ch=0; 
	int nread=0;
	int peek_character = -1; 

	if(peek_character != -1) 
		return 1; 

	new_settings->c_cc[VMIN]=0; 
	tcsetattr(0, TCSANOW, new_settings); 
	nread = read(0,&ch,1); 
	new_settings->c_cc[VMIN]=1; 
	tcsetattr(0, TCSANOW, new_settings); 

	if(nread == 1)
	{ 
		peek_character = ch; 
		*valeur = ch;
		return 1; 
	} 
	return 0; 
}



